package edu.zueb.sport.config;

import java.util.concurrent.ThreadPoolExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.core.task.support.ContextPropagatingTaskDecorator;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * @author jasonfu
 * @date 2024/9/24 16:48
 */
@Slf4j
@Configuration
public class ThreadPoolConfig {

    /**
     * 配置并创建一个名为"amberAsyncThreadPool"的线程池
     * 该线程池旨在处理异步任务，其配置基于可用的CPU核心数
     *
     * @return ThreadPoolTaskExecutor 实例，用于执行异步任务
     */
    @Bean("amberAsyncThreadPool")
    public ThreadPoolTaskExecutor amberAsyncThreadPool() {
        // 获取当前系统的CPU核心数
        int processors = Runtime.getRuntime().availableProcessors();
        // 日志记录CPU核心数
        log.info("cpu核数={}", processors);

        // 如果获取到的CPU核心数小于等于0，则默认使用4作为核心数
        if (processors <= 0) {
            processors = 4;
            // 记录警告信息，提示使用默认核心数
            log.warn("无法获取有效的cpu核数，默认按4核处理");
        }

        // 创建线程池任务执行器实例
        ThreadPoolTaskExecutor executor = buildThreadPoolTaskExecutor(processors);
        // 初始化线程池
        executor.initialize();

        // 返回配置好的线程池任务执行器实例
        return executor;
    }

    /**
     * 创建一个名为"amberVirtualThreadPool"的Bean，该Bean是一个VirtualThreadTaskExecutor实例
     * 用于执行虚拟线程任务，每个任务在单独的虚拟线程中运行
     *
     * @return VirtualThreadTaskExecutor实例，用于管理虚拟线程池
     */
    @Bean("amberVirtualThreadPool")
    public VirtualThreadTaskExecutor amberVirtualThreadPool() {
        return new VirtualThreadTaskExecutor("Amber-Virtual-");
    }

    /**
     * 构建一个配置好的ThreadPoolTaskExecutor
     * 该方法根据处理器核心数配置线程池，以优化异步任务的执行效率
     *
     * @param processors 处理器核心数，用于计算线程池的相关容量
     * @return 配置好的ThreadPoolTaskExecutor实例
     */
    private static ThreadPoolTaskExecutor buildThreadPoolTaskExecutor(int processors) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数为CPU核心数的两倍
        executor.setCorePoolSize(processors * 2);
        // 设置最大线程数为CPU核心数的四倍
        executor.setMaxPoolSize(processors * 4);
        // 设置线程池的队列容量为CPU核心数
        executor.setQueueCapacity(processors);
        // 设置线程的空闲存活时间为30秒
        executor.setKeepAliveSeconds(30);
        // 设置线程名称前缀，便于识别和管理
        executor.setThreadNamePrefix("Amber-Async-");
        // 设置拒绝执行任务的处理策略为调用者运行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 设置任务装饰器，用于传播上下文信息
        executor.setTaskDecorator(new ContextPropagatingTaskDecorator());
        return executor;
    }
}
